package com.hnblc.blcwms.common.exceptions;

//import com.alibaba.fastjson.serializer.JSONSerializer;
//import com.alibaba.fastjson.serializer.PropertyFilter;
//import com.alibaba.fastjson.serializer.SerializeWriter;
//import com.neusoft.ecommerce.core.base.BaseConvert;
import lombok.ToString;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * 
 * GeneralException
 *
 * @author <A>cheng.yy@neusoft.com</A>
 *
 * @date Apr 15, 2015
 *
 * @Copyright: © 2001-2015 东软集团股份有限公司
 *
 */
@ToString
public class GeneralException extends RuntimeException/* implements BaseConvert */{

    private static final long serialVersionUID = 1633213333563068730L;

    /**
     * local
     */
    private Locale defaultLocale = Locale.getDefault();
    /**
     * resource name
     */
    private static final String RESOURCE_NAME = "i18n.exceptions";
    /**
     * message prefix
     */
    private static final String MESSAGE_PREFIX = "ERROR";

    /**
     * header 分隔符
     */
    private static final String HEADER_DELIMITER = "-";
    /**
     * 文字分隔符
     */
    private static final String MESSAGE_DELIMITER = ": ";

    /**
     * 异常消息类型
     */
    private String category = null;

    /**
     * 异常代码
     */
    private String errorCode = null;
    /**
     * 异常参数
     */
    private Object[] arguments;

    /**
     * 业务操作代码
     */
    private int optionCode;

    /**
     * 构造器
     * 
     * @param errorDescription
     *            错误定义
     */
    public GeneralException(final ErrorDescription errorDescription) {
        errorCode = errorDescription.getErrorCode().substring(2);
        category = errorDescription.getErrorCode().substring(0, 2);
    }

    /**
     * 构造器
     * 
     * @param errorDescription
     *            错误定义
     * @param args
     *            参数
     */
    public GeneralException(final ErrorDescription errorDescription,
                            final Object... args) {
        errorCode = errorDescription.getErrorCode().substring(2);
        category = errorDescription.getErrorCode().substring(0, 2);
        arguments = args;
        if (args.length > 0) {
            if (args[0] instanceof GeneralException) {
                GeneralException exception = (GeneralException) args[0];
                errorCode = exception.errorCode;
                category = exception.category;
                arguments = exception.arguments;
            }
        }
    }

    /**
     * 构造器
     * 
     * @param option
     *            业务代码（自定义）
     * @param args
     *            消息参数
     */
    public GeneralException(final int option, final Object... args) {
        errorCode = ErrorDescription.ERROR_BUSINESS_1.getErrorCode().substring(
                2);
        category = ErrorDescription.ERROR_BUSINESS_1.getErrorCode().substring(
                0, 2);
        arguments = args;
        optionCode = option;
        if (args.length > 0) {
            if (args[0] instanceof GeneralException) {
                GeneralException exception = (GeneralException) args[0];
                errorCode = exception.errorCode;
                category = exception.category;
                arguments = exception.arguments;
            }
        }
    }

    /**
     * 构造器
     * 
     * @param throwable
     *            Throwable
     */
    public GeneralException(final Throwable throwable) {
        this(ErrorDescription.ERROR_OTHER_1, throwable);
    }

    /**
     * 获取category
     * 
     * @return category
     */
    public final String getCategory() {
        return category;
    }

    /**
     * 获取errorCode
     * 
     * @return errorCode
     */
    public final String getErrorCode() {
        return errorCode;
    }

    /**
     * 获取code
     * 
     * @return code
     */
    public String getCode() {
        return MESSAGE_PREFIX + HEADER_DELIMITER + category + HEADER_DELIMITER
                + errorCode;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Throwable#getMessage()
     */
    @Override
    public String getMessage() {
        return getLocalizedMessage();
    }

    /**
     * 获取业务标识
     * 
     * @return optionCode
     */
    public int getOptionCode() {
        return optionCode;
    }

    /**
     * 设置业务标识
     * 
     * @param optionCode
     */
    public void setOptionCode(int optionCode) {
        this.optionCode = optionCode;
    }

    /**
     * 获取Bundel
     * 
     * @param locale
     * @return Bundel
     */
    private ResourceBundle getBundle(final Locale locale) {
        ResourceBundle resourceBundle = ResourceBundle.getBundle(getBaseName(),
                locale);
        if (resourceBundle.getLocale().getLanguage()
                .equals(locale.getLanguage())) {
            return resourceBundle;
        }

        return ResourceBundle.getBundle(getBaseName());
    }

    /**
     * 获取baseName
     * 
     * @return baseName
     */
    private String getBaseName() {
        return RESOURCE_NAME;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Throwable#getLocalizedMessage()
     */
    @Override
    public final String getLocalizedMessage() {
        return getLocalizedMessage(getDefaultLocale(),true);
    }

    /**
     * 获取LocalizedMessage
     * 
     * @param locale
     * @return LocalizedMessage
     */
    public final String getLocalizedMessage(final Locale locale,boolean showCode) {
        ResourceBundle resourceBundle = this.getBundle(locale);
        String resouceBundleLanguage = resourceBundle.getLocale().getLanguage();

        if (resouceBundleLanguage.length() == 0) {
            resouceBundleLanguage = Locale.getDefault().getLanguage();
        }

        if (!resouceBundleLanguage.equals(locale.getLanguage())) {
            return null;
        }
        String message = "";
        message += MESSAGE_PREFIX;
        message += HEADER_DELIMITER;
        message += category;
        message += HEADER_DELIMITER;
        message += errorCode;
        String key = message;// ERROR-10000001
        message += MESSAGE_DELIMITER;
        String detailFormatString = null;
        detailFormatString = MessageFormat.format(resourceBundle.getString(key), arguments);
        message += detailFormatString;
        if (!showCode)
            return detailFormatString;
        else
            return message;
    }

    public final String getSingleMessage(){
        return getLocalizedMessage(getDefaultLocale(),false);
    }

    /**
     * 获取local
     * 
     * @return local
     */
    public final Locale getDefaultLocale() {
        return this.defaultLocale;
    }

/*    *//*
     * (non-Javadoc)
     * 
     * @see com.neusoft.ecommerce.core.base.BaseConvert#convertToJson()
     *//*
    @Override
    public String convertToJson() {
        PropertyFilter filters = new PropertyFilter() {
            // 过滤不需要的字段
            public boolean apply(Object source, String name, Object value) {
                return !"suppressed".equals(name);
            }
        };
        SerializeWriter sw = new SerializeWriter();
        JSONSerializer serializer = new JSONSerializer(sw);
        serializer.getPropertyFilters().add(filters);
        serializer.write(this);
        return sw.toString();
    }*/

}
